<?php

namespace wechatpay;



class WxApp
{

    /**
     * 配置參數
     */
    public $config = array(
        'appid' => "wx94387bb5f65b2c85",    /*微信开放平台上的应用id*/
        'mch_id' => "1536418351",   /*微信申请成功之后邮件中的商户id*/
        'api_key' => "abcdefghigklmnopqrstuvwxyz123456",    /*在微信商户平台上自己设定的api密钥 32位*/
    );


    //下单
    public function getPrePayOrder($body, $out_trade_no, $total_fee,$notify_url,$spbill_create_ip,$attach=false)
    {
        $url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
        $onoce_str = $this->createNoncestr();
        $data["appid"] = $this->config["appid"];
        $data["body"] = $body;
        $data["mch_id"] = $this->config['mch_id'];
        $data["nonce_str"] = $onoce_str;
        $data["notify_url"] = $notify_url;
        $data["out_trade_no"] = $out_trade_no;
        $data["spbill_create_ip"] = $spbill_create_ip;
        $data["total_fee"] = $total_fee*100;
        $data["trade_type"] = "APP";
        $sign = $this->getSign($data);
        $data["sign"] = $sign;
        if($attach){
            $data["attach"] = json_encode($attach);
        }
        $xml = $this->arrayToXml($data);
        $response = $this->postXmlCurl($xml, $url);
        //将微信返回的结果xml转成数组
        $response = $this->xmlToArray($response);
        dump($total_fee);
        $arr=[
            'appid'=>$response['appid'],
            'partnerid'=>$this->config['mch_id'],
            'prepayid'=>$response['prepay_id'],
            'package'=>'Sign=WXPay',
            'noncestr'=>$this->createNoncestr(),
            'timestamp'=>time(),
        ];
        $arr_sign = $this->getSign($arr);
        $arr['sign']=$arr_sign;
        //返回数据
        return $arr;
    }


    public function getSign($Obj)
    {
        foreach ($Obj as $k => $v) {
            $Parameters[$k] = $v;
        }
    //签名步骤一：按字典序排序参数
        ksort($Parameters);
        $String = $this->formatBizQueryParaMap($Parameters, false);
    //echo '【string1】'.$String.'</br>';
    //签名步骤二：在string后加入KEY
        $String = $String . "&key=" . $this->config['api_key'];
    //echo "【string2】".$String."</br>";
    //签名步骤三：MD5加密
        $String = md5($String);
    //echo "【string3】 ".$String."</br>";
    //签名步骤四：所有字符转为大写
        $result_ = strtoupper($String);
    //echo "【result】 ".$result_."</br>";
        return $result_;
    }


    /**
     *  作用：产生随机字符串，不长于32位
     */
    public function createNoncestr($length = 32)
    {
        $chars = "abcdefghijklmnopqrstuvwxyz0123456789";
        $str = "";
        for ($i = 0; $i < $length; $i++) {
            $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
        }
        return $str;
    }


//数组转xml
    public function arrayToXml($arr)
    {
        $xml = "<xml>";
        foreach ($arr as $key => $val) {
            if (is_numeric($val)) {
                $xml .= "<" . $key . ">" . $val . "</" . $key . ">";
            } else {
                $xml .= "<" . $key . "><![CDATA[" . $val . "]]></" . $key . ">";
            }
        }
        $xml .= "</xml>";
        return $xml;
    }


    /**
     *  作用：将xml转为array
     */
    public function xmlToArray($xml)
    {
//将XML转为array
        $array_data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
        return $array_data;
    }


    /**
     *  作用：以post方式提交xml到对应的接口url
     */
    public function postXmlCurl($xml, $url, $second = 30)
    {
//初始化curl
        $ch = curl_init();
//设置超时
        curl_setopt($ch, CURLOPT_TIMEOUT, $second);
//这里设置代理，如果有的话
//curl_setopt($ch,CURLOPT_PROXY, '8.8.8.8');
//curl_setopt($ch,CURLOPT_PROXYPORT, 8080);
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
//设置header
        curl_setopt($ch, CURLOPT_HEADER, FALSE);
//要求结果为字符串且输出到屏幕上
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
//post提交方式
        curl_setopt($ch, CURLOPT_POST, TRUE);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
//运行curl
        $data = curl_exec($ch);
//返回结果

        if ($data) {
            curl_close($ch);
            return $data;
        } else {
            $error = curl_errno($ch);
            echo "curl出错，错误码:$error" . "<br>";
            curl_close($ch);
            return false;
        }
    }


    /*
    获取当前服务器的IP
    */
    public function get_client_ip()
    {
        if ($_SERVER['REMOTE_ADDR']) {
            $cip = $_SERVER['REMOTE_ADDR'];
        } elseif (getenv("REMOTE_ADDR")) {
            $cip = getenv("REMOTE_ADDR");
        } elseif (getenv("HTTP_CLIENT_IP")) {
            $cip = getenv("HTTP_CLIENT_IP");
        } else {
            $cip = "unknown";
        }
        return $cip;
    }


    /**
     *  作用：格式化参数，签名过程需要使用
     */
    public function formatBizQueryParaMap($paraMap, $urlencode)
    {
        $buff = "";
        ksort($paraMap);
        foreach ($paraMap as $k => $v) {
            if ($urlencode) {
                $v = urlencode($v);
            }
            $buff .= $k . "=" . $v . "&";
        }
        $reqPar='';
        if (strlen($buff) > 0) {
            $reqPar = substr($buff, 0, strlen($buff) - 1);
        }
        return $reqPar;
    }
}